<?php
/**
 *
 *
 *
 */
abstract class Yz_Form_Parser_Abstract
    extends Yz_Class
    implements Yz_Form_Parser_Interface
{


    protected $errors = array();


    /**
     *  @var Yz_Form_Interface
     */
    protected $form;

    /****************************
     *      Public methods      *
     ****************************/


    public function __construct(Yz_Form_Interface $form)
    {
        $this->form = $form;
    }


    /**
     *  @param form
     *  @param ArrayAccess values to be parsed
     *  @return int number of errors
     */
    public function parse(Yz_Hash $input, Yz_Item_Interface $item)
    {
        debug();
        $this->errors = array();
        foreach ($this->form as $element) {

            // whether to ignore element
            if (! $element->isParseable())
                continue;
            // TODO callbacks
            try {
                $this->parseElement($element, $input)
                    and $item[$element->getName()] = $element->getValue();
                ;
            } catch (Yz_Item_Exception $ex) {
                // assignment failure
                debug($ex);
                $this->errors[] = $ex;
            } catch (Yz_Form_Element_Exception $ex) {
                // parse failure
                debug($ex);
                $this->errors[] = $ex;
            }
        }
        if ($this->errors)
            throw new Yz_Form_Parser_Exception;
        return $this;
    }

    /**
     *  these may be element-related as well as global
     */
    final public function getErrors()
    {
        return $this->errors;
    }


    protected function parseElement(Yz_Form_Element_Interface $element, Yz_Hash $input)
    {
        $val = $input->offsetGet($element->getName());
        if (null === $val)
            throw Yz_Form_Parser_Exception::_new('Invalid form submitted');
        return $element->parse($val);
        /* ### OLD
        $callback = "parseElement_".$element->name;
        if (method_exists($this, $callback)) {
            return $this->$callback($element, $values);
        }
        return $this->parseElementDefault($element, $values);
        */
    }


}
